#include "networkmanager.h"
#include "networkpostrequest.h"
#include "networkgetrequest.h"
#include "network/networkmanager.h"
#include "zingme/networkzingmeconnection.h"
#include "zingme/networkzingmemanager.h"
#include "account/accountmanager.h"
#include "account/accountloginner.h"
#include <json.h>

#include <QNetworkAccessManager>
#include <QDebug>
#include <QVariant>
#include <QTextStream>
#include <QDate>


namespace Network {

Manager *Manager::m_instance = NULL;
QString Manager::m_server = QString("chat.realtime.me.zing.vn");
int Manager::m_port = 5050;
//QString Manager::m_server = QString("ws://49.213.67.22");
//int Manager::m_port = 8181;
Manager::Manager(QObject *parent) :
    QObject(parent),
    m_connection(NULL),
    m_networkAccessManager(new QNetworkAccessManager(this))
{
   // setConnection();
    connect(Account::Loginner::instance(), &Account::Loginner::logined,
            this, &Manager::onLogined);
}

Manager *Manager::instance(QObject *parent)
{
    if (m_instance == NULL)
        m_instance = new Zingme::Manager(parent);
    return m_instance;
}

void Manager::setConnection() const
{
    connect(m_connection, &Connection::connected,
            this, &Manager::onConnected);
    connect(m_connection, &Connection::received,
            this, &Manager::onReceived);
    connect(m_connection, &Connection::disconnected,
            this, &Manager::onDisconnected);
    connect(Account::Loginner::instance(), &Account::Loginner::logouted,
            this, &Manager::onLogouted);
}

bool Manager::post(Request *request)
{
    return request->post(this);
}

void Manager::onLogined(bool successed, const QString &message, const QString &sessionKey)
{
    Q_UNUSED(message)
    if (!successed)
        return;

    m_sessionKey = sessionKey;
    if(m_connection == NULL) {
        m_connection = new Zingme::Connection(this);
        setConnection();
    }
    qDebug() << "do connect to websocket " << sessionKey;
    m_connection->connect(Manager::m_server, Manager::m_port, params());
    emit sessionKeyReady();
}

void Manager::onLogouted()
{
    logout();
}

void Manager::logout()
{
    m_sessionKey = QString();
    if (m_connection == NULL)
        return;

    m_connection->disconnect();
    delete m_connection;
    m_connection = NULL;
}

void Manager::onConnected()
{
    if (m_connection == NULL)
        return;
    emit connected();
}


void Manager::onReceived(QByteArray message)
{
    //qDebug() << message;
    JsonReader reader;
    QTextStream stream(message);
    QVariant variant;
    if (!reader.read(stream, variant))
        return;

    if (variant.type() != QVariant::Map)
        return;

    QVariantMap map = variant.toMap();
    if (!map.contains("r"))
        return;

    QVariant errorVar = map.value("r");
    if (errorVar.type() != QVariant::String)
        return;

    bool ok;
    int error = errorVar.toString().toInt(&ok);
    if (!ok)
        return;

    if (error != 0)
        return;

    QVariant commandVar = map.value("cmd");
    if (commandVar.type() != QVariant::String)
        return;

    QString commandId = commandVar.toString();
    if (!map.contains("data"))
        return;

    emit received(commandId, map.value("data"));
}

void Manager::onDisconnected()
{
    qDebug() << "onDisconnected ";
    emit disconnected();
}

} // namespace Network
